home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb-4.5 / dist / bfd / cpu-h8300.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-27  |  9.8 KB  |  433 lines

  1. /* BFD library support routines for the Hitachi H8/300 architecture.
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Hacked by Steve Chamberlain of Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "bfd.h"
  22. #include "sysdep.h"
  23. #include "libbfd.h"
  24.  
  25. #define DEFINE_TABLE 
  26. #include "opcode/h8300.h"
  27.  
  28. #define MAXSAME 14
  29.  
  30. static struct h8_opcode * h8_opcodes_sorted[256][MAXSAME];
  31.  
  32. /* Run through the opcodes and sort them into order to make them easy
  33.    to disassemble
  34.  */
  35. static void
  36. DEFUN_VOID(bfd_h8_disassemble_init)
  37. {
  38.   unsigned int i;    
  39.   struct h8_opcode *p; 
  40.     
  41.   for (p = h8_opcodes; p->name; p++) {    
  42.     int n1 = 0;
  43.     int n2 = 0;
  44.  
  45.     if ((int)p->data.nib[0] < 16) {
  46.       n1 =(int) p->data.nib[0] ;
  47.     } else n1 = 0;
  48.     if ((int)p->data.nib[1] < 16) {
  49.       n2 = (int) p->data.nib[1];
  50.     }else n2 = 0;
  51.  
  52.     for (i = 0; i < MAXSAME; i++) {
  53.       int j = n1 * 16 + n2;
  54.       if (h8_opcodes_sorted[j][i] == (struct h8_opcode *)NULL) {
  55.     h8_opcodes_sorted[j][i] = p;
  56.     break;
  57.       }
  58.     }
  59.     
  60.     if (i==MAXSAME)abort();
  61.  
  62.     /* Just make sure there are an even number of nibbles in it, and
  63.        that the count is the same s the length */
  64.     for (i = 0; p->data.nib[i] != E; i++) 
  65.      /*EMPTY*/;
  66.     if (i & 1) abort();
  67.     p->length = i/2;
  68.   }
  69.   for (i = 0; i < 256; i++) 
  70.       {
  71.     if (h8_opcodes_sorted[i][0]) 
  72.       p = h8_opcodes_sorted[i][0];
  73.     else h8_opcodes_sorted[i][0] = p;
  74.       }
  75. }
  76.  
  77.  
  78. unsigned int
  79. DEFUN(bfd_h8_disassemble,(addr, data, stream),
  80. bfd_vma addr AND
  81. CONST bfd_byte *data AND
  82. FILE *stream)
  83. {
  84.   /* Find the first entry in the table for this opcode */
  85.   CONST static char *regnames[] = {
  86.     "r0h","r1h","r2h","r3h","r4h","r5h","r6h","r7h",
  87.     "r0l","r1l","r2l","r3l","r4l","r5l","r6l","r7l" };
  88.  
  89.   int rs = 0;
  90.   int rd = 0;
  91.   int rdisp = 0;
  92.   int abs = 0;
  93.   struct h8_opcode **p = h8_opcodes_sorted[(unsigned)(data[0])];
  94.   struct h8_opcode *q;
  95.  
  96.   /* Find the exact opcode/arg combo */
  97.   while (*p) {
  98.     op_type *nib;
  99.     unsigned int len = 0;
  100.     q = *p++;
  101.     nib  =q->data.nib;
  102.     while (*nib != E) {
  103.       op_type looking_for = *nib;
  104.       int thisnib = data[len>>1] ;
  105.       thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
  106.       if ((int)looking_for & (int)B31) {
  107.     if (((int)thisnib & 0x8) ==0) goto fail;
  108.     looking_for = (op_type)((int)looking_for &  ~(int)B31);
  109.       }
  110.       if ((int)looking_for & (int)B30) {
  111.     if (((int)thisnib & 0x8) !=0) goto fail;
  112.     looking_for = (op_type)((int)looking_for &  ~(int)B30);
  113.       }
  114.       switch (looking_for) {
  115.       case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 
  116.       case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
  117.     if ((int)looking_for != thisnib) goto fail;
  118.     break;
  119.       case ABS16SRC:
  120.       case ABS16OR8SRC:
  121.       case ABS16ORREL8SRC:
  122.       case ABS16DST:
  123.       case ABS16OR8DST:
  124.       case DISPSRC:
  125.       case DISPDST:
  126.       case IMM16:
  127.     abs = (data[len>>1]) * 256 + data[(len+2)>>1];
  128.     len+=3;
  129.     nib+=3;
  130.     break;
  131.       case DISPREG:
  132.     rdisp = thisnib; 
  133.     break;
  134.       case KBIT:
  135.     abs = thisnib == 0x8 ? 2:1;
  136.     break;
  137.       case IMM8:
  138.       case ABS8SRC:
  139.       case ABS8DST:
  140.       case MEMIND:
  141.       case DISP8:
  142.     abs= data[len>>1];
  143.     len++;
  144.     nib++;
  145.     break;
  146.       case IMM3:
  147.     abs = thisnib ;
  148.     break;
  149.       case RS8:
  150.       case RS16:
  151.       case RSINC:
  152.       case RSIND:
  153.     rs = thisnib;
  154.     break;
  155.       case RD16:
  156.       case RDDEC:
  157.       case RD8:
  158.       case RDIND:
  159.     rd = thisnib;
  160.     break;
  161.       default:
  162.     fprintf(stream, "Dont understand \n");
  163.     goto found;
  164.       }
  165.       len++;
  166.       nib++;
  167.     }
  168.     goto found;
  169.   fail: 
  170.     ;
  171.  
  172.   }
  173.   fprintf(stream, "%02x %02x        .word\tH'%x,H'%x",
  174.       data[0], data[1],
  175.       data[0], data[1]);
  176.   return 2;
  177.  found:;
  178.     { int i;
  179.  
  180.       for (i = 0; i < q->length; i++) {
  181.     fprintf(stream, "%02x ", data[i]);
  182.       }
  183.       for (; i < 6; i++) {
  184.     fprintf(stream, "   ");
  185.       }
  186.     }
  187.   fprintf(stream, "%s\t",q->name);
  188.   /* Now print out the args */
  189.     {
  190.       op_type *args = q->args.nib;
  191.       int hadone = 0;
  192.       while (*args != E) {
  193.     if (hadone)
  194.       fprintf(stream, ",");
  195.     switch ((int)(*args) & ~((int)B30|(int)B31)) {
  196.     case IMM16:
  197.     case IMM8:
  198.     case IMM3:
  199.       fprintf(stream, "#0x%x", (unsigned)abs); 
  200.       break;
  201.     case RD8:
  202.       fprintf(stream, "%s", regnames[rd]); 
  203.       break;
  204.     case RS8:
  205.       fprintf(stream, "%s",regnames[rs]);
  206.       break;
  207.     case RD16:
  208.       fprintf(stream, "r%d", rd& 0x7);
  209.       break;
  210.     case RS16:
  211.       fprintf(stream, "r%d", rs & 0x7);
  212.       break;
  213.     case RSINC:
  214.       fprintf(stream, "@r%d+", rs & 0x7);
  215.       break;
  216.     case RDDEC:
  217.       fprintf(stream, "@-r%d", rd & 0x7);
  218.       break;
  219.     case RDIND: 
  220.       fprintf(stream, "@r%d", rd & 0x7);
  221.       break;
  222.     case RSIND:
  223.       fprintf(stream, "@r%d",rs & 0x7);
  224.       break;
  225.     case ABS8SRC:
  226.     case ABS16SRC:
  227.     case ABS16OR8SRC:
  228.     case ABS16ORREL8SRC:
  229.     case ABS16OR8DST:
  230.     case ABS16DST:
  231.     case ABS8DST:
  232.       fprintf(stream, "@0x%x", (unsigned)abs);
  233.       break;
  234.     case MEMIND:
  235.       fprintf(stream, "@@%d (%x)",abs, abs);
  236.       break;
  237.     case DISP8:
  238.       fprintf(stream, ".%s%d (%x)",(char)abs>0 ? "+" :"", (char)abs,
  239.           addr + (char)abs + 2);
  240.       break;
  241.     case DISPSRC:
  242.     case DISPDST:
  243.       fprintf(stream, "@(0x%x,r%d)", abs, rdisp & 0x7); 
  244.       break;
  245.     case CCR:
  246.       fprintf(stream, "ccr"); 
  247.       break;
  248.     case KBIT:
  249.       fprintf(stream, "#%d",abs); 
  250.       break;
  251.     default:
  252.       abort();
  253.     }
  254.     hadone = 1;
  255.     args++;
  256.       }
  257.     }
  258.   return q->length;
  259. }
  260.  
  261.  
  262.  
  263. unsigned int DEFUN(print_insn_h8300,(addr, data, file),
  264. bfd_vma addr AND
  265. CONST char *data AND
  266. PTR file)
  267. {
  268.   static boolean init;
  269.   if (!init) {
  270.     bfd_h8_disassemble_init();
  271.     init= true;
  272.   }
  273.  
  274.   return   bfd_h8_disassemble(addr, (bfd_byte *)data, file);
  275. }
  276.  
  277. /* 
  278. Relocations for the H8
  279.  
  280. */
  281. static bfd_reloc_status_type 
  282. DEFUN(howto16_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
  283. bfd *abfd AND
  284. arelent *reloc_entry AND
  285. struct symbol_cache_entry *symbol_in AND
  286. PTR data AND
  287. asection *ignore_input_section)
  288. {
  289.   long relocation = 0;
  290.   bfd_vma addr = reloc_entry->address;
  291.   long x = bfd_get_16(abfd, (bfd_byte *)data + addr);
  292.  
  293.   HOWTO_PREPARE(relocation, symbol_in);
  294.  
  295.   x = (x + relocation + reloc_entry->addend);
  296.  
  297.   bfd_put_16(abfd, x, (bfd_byte *)data + addr);
  298.   return bfd_reloc_ok;
  299. }
  300.  
  301.  
  302. static bfd_reloc_status_type 
  303. DEFUN(howto8_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
  304. bfd *abfd AND
  305. arelent *reloc_entry AND
  306. struct symbol_cache_entry *symbol_in AND
  307. PTR data AND
  308. asection *ignore_input_section)
  309. {
  310.   long relocation = 0;
  311.   bfd_vma addr = reloc_entry->address;
  312.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  313.  
  314.   HOWTO_PREPARE(relocation, symbol_in);
  315.  
  316.   x = (x + relocation + reloc_entry->addend);
  317.  
  318.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  319.   return bfd_reloc_ok;
  320. }
  321.  
  322.  
  323. static bfd_reloc_status_type 
  324. DEFUN(howto8_FFnn_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
  325. bfd *abfd AND
  326. arelent *reloc_entry AND
  327. struct symbol_cache_entry *symbol_in AND
  328. PTR data AND
  329. asection *ignore_input_section)
  330. {
  331.   long relocation = 0;
  332.   bfd_vma addr = reloc_entry->address;
  333.  
  334.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  335.   abort();
  336.   HOWTO_PREPARE(relocation, symbol_in);
  337.  
  338.   x = (x + relocation + reloc_entry->addend);
  339.  
  340.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  341.   return bfd_reloc_ok;
  342. }
  343.  
  344. static bfd_reloc_status_type 
  345. DEFUN(howto8_pcrel_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
  346. bfd *abfd AND
  347. arelent *reloc_entry AND
  348. struct symbol_cache_entry *symbol_in AND
  349. PTR data AND
  350. asection *ignore_input_section)
  351. {
  352.   long relocation = 0;
  353.   bfd_vma addr = reloc_entry->address;
  354.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  355.   abort();
  356.   HOWTO_PREPARE(relocation, symbol_in);
  357.  
  358.   x = (x + relocation + reloc_entry->addend);
  359.  
  360.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  361.   return bfd_reloc_ok;
  362. }
  363.  
  364.  
  365.  
  366. static reloc_howto_type howto_16
  367.   = NEWHOWTO(howto16_callback,"abs16",1,false,false);
  368. static reloc_howto_type howto_8
  369.   = NEWHOWTO(howto8_callback,"abs8",0,false,false);
  370.  
  371. static reloc_howto_type howto_8_FFnn
  372.   = NEWHOWTO(howto8_FFnn_callback,"ff00+abs8",0,false,false);
  373.  
  374. static reloc_howto_type howto_8_pcrel
  375.   = NEWHOWTO(howto8_pcrel_callback,"pcrel8",0,false,true);
  376.  
  377.  
  378. static CONST struct reloc_howto_struct *
  379. DEFUN(local_bfd_reloc_type_lookup,(arch, code),
  380.  CONST struct bfd_arch_info *arch AND
  381.  bfd_reloc_code_type code)
  382. {
  383.   switch (code) {
  384.   case BFD_RELOC_16:
  385.     return &howto_16;
  386.   case BFD_RELOC_8_FFnn:
  387.     return &howto_8_FFnn;
  388.   case BFD_RELOC_8:
  389.     return &howto_8;
  390.   case BFD_RELOC_8_PCREL:
  391.     return &howto_8_pcrel;
  392.   }
  393.   return (reloc_howto_type *)NULL;
  394. }
  395.  
  396. int bfd_default_scan_num_mach();
  397.  
  398. static boolean 
  399. DEFUN(h8300_scan,(info, string),
  400. CONST struct bfd_arch_info *info AND
  401. CONST char *string)
  402. {
  403.   if (strcmp(string,"h8300") == 0) return true;
  404.   if (strcmp(string,"H8300") == 0) return true;
  405.   if (strcmp(string,"h8/300") == 0) return true;
  406.   if (strcmp(string,"H8/300") == 0) return true;
  407.   return false;
  408. }
  409.  
  410. static bfd_arch_info_type arch_info_struct = 
  411.   {
  412.     16,    /* 16 bits in a word */
  413.     16,    /* 16 bits in an address */
  414.     8,    /* 8 bits in a byte */
  415.     bfd_arch_h8300,
  416.     0,    /* only 1 machine */
  417.     "H8/300", /* arch_name  */
  418.     "H8/300", /* printable name */
  419.     1,
  420.     true,    /* the default machine */
  421.     bfd_default_compatible,
  422.     h8300_scan,
  423.     print_insn_h8300,
  424.     local_bfd_reloc_type_lookup,
  425.     0,
  426.   };
  427.  
  428. void
  429. DEFUN_VOID(bfd_h8300_arch)
  430. {
  431.   bfd_arch_linkin(&arch_info_struct);
  432. }
  433.